#include <pic18f452.h>

#define VERSION "000100"
 
/* MicroController Frequency */
#define FOSC 20000000
#define TOSC 50
#define NANOSEC 1000000000
#define MICROSEC 1000000
#define MILLISEC 1000
#define TPNS (4*(NANOSEC / FOSC))

/* Leds */
#define LED_YELLOW PORTBbits.RB7
#define LED_GREEN PORTBbits.RB6
#define SETLEDOUTPUTPORTS TRISBbits.TRISB7=TRISBbits.TRISB6=0

/** Motors **/
#define STEPS360 200
#define PHIA PORTDbits.RD0
#define PHIB PORTDbits.RD1
#define ENA PORTCbits.RC2
#define ENB PORTCbits.RC1
#define SETMOTOROUTPUTPORTS TRISDbits.TRISD0=TRISDbits.TRISD1=TRISCbits.TRISC2=TRISCbits.TRISC1=0

#define MICROSTEPS 0x1
// WINDINGB_MASK = 0x2 << LN(MICROSTEPS)
#define WINDINGB_MASK 0x2
// #define WINDINGB_MASK 0x10
// WINDINGA_MASK = 0x3 << LN(MICROSTEPS)
#define WINDINGA_MASK 0x3
//#define WINDINGA_MASK 0x18

#define SETPHIA(microstep) if ((((microstep & WINDINGA_MASK) == 0) || ((microstep & WINDINGA_MASK) == WINDINGA_MASK))!=0) PHIA=0; else PHIA=1
#define SETPHIB(microstep) if ((microstep & WINDINGB_MASK) !=0) PHIB=0; else  PHIB=1

/* Motor status */
#define INITIALIZED 0x0100
#define RUNNING 0x0001
#define SLEWMODE 0X0010
#define BACKWARD 0x0020
#define HIGHSPEED 0x0040
#define SETMOTORPROPERTY(motorstatus, property) motorstatus |= property
#define UNSETMOTORPROPERTY(motorstatus, property) motorstatus &= ~property
#define GETMOTORPROPERTY(motorstatus, property) (motorstatus & property)

/* Timer period */
#define MICROSECONDS 1000000
#define TICKS_MICRO 1000 / (4 * TOSC)
#define MIN_TICKS  16


//#define SETTIMER TMR1H=motors[0].timer.timer.fields.valueh;TMR1L=motors[0].timer.timer.fields.valuel;
#define SETTIMER {unsigned char ps=(motor.treg / 65536) + 1;  motor.timer.count=ps;   motor.timer.current=0; motor.timer.timer.value = 65536 - (motor.treg/ps); TMR1H=motor.timer.timer.fields.valueh;TMR1L=motor.timer.timer.fields.valuel;}
#define RESETTIMER {TMR1H=motor.timer.timer.fields.valueh;TMR1L=motor.timer.timer.fields.valuel;}

#define SETREG(reg, mask) *reg |= mask
#define UNSETREG(reg, mask) *reg &= ~mask

#define STARTTIMER T1CONbits.TMR1ON = 1; 
#define STOPTIMER T1CONbits.TMR1ON = 0; 

/* Motor acceleration/deceleration */
// Speed ramp states
#define STOP  0
#define ACCEL 1
#define DECEL 2
#define RUN   3
#define SPEEDCHANGE 4
#define STOPPING 5
#define DECELSTOP 6

typedef union {
  unsigned int value;
  struct { unsigned char valueh; unsigned char valuel; } fields;
} TimerRegister;

typedef struct {
  unsigned char count;
  unsigned char current;
  TimerRegister timer;
} TimerValue;


typedef struct {
  unsigned int status; // lowspeed, forward, slew mode, stopped
  unsigned long position;
  unsigned int current_speed;
  unsigned int target_speed;
  unsigned char microstep;
  unsigned char pwmindex;
  unsigned long breaks;
  TimerValue timer;
  unsigned char phase;
  unsigned long treg;
  float ta;
  unsigned long timerfinal;
  unsigned int alpha; // acceleration in deg/s^2
  unsigned char id;
} AxisData;


extern AxisData motors[];


